﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Reflection;
using System.Xml.XPath;
using System.Drawing;
using BoneSoft.CSS;

namespace OpenControls.Core
{
    public class ControlsConfiguration
    {
        /// <summary>
        /// Gets or sets all loaded customization and they are ready-to-use.
        /// </summary>
        public static IDictionary<string, IStyle> LoadedCustomizations = new Dictionary<string, IStyle>();

        /// <summary>
        /// Gets or sets assemblies with  XML customizations.
        /// </summary>
        private IList<Assembly> assemblies = new List<Assembly>();

        public ControlsConfiguration()
        {

        }
        
        /// <summary>
        /// Add an assembly that contains the customizations files.
        /// </summary>
        /// <param name="assembly">Assembly that contains the customization files to be loaded.</param>
        public ControlsConfiguration AddAssembly(Assembly assembly)
        {
            this.assemblies.Add(assembly);
            return this;
        }

        /// <summary>
        /// This method will prepare all customizations added to all Assemblies loaded.
        /// </summary>
        public void BuildCustomizations()
        {
            Scanner scanner;
            Parser parser;
            IStyle currentStyle;

            foreach (var currentAssembly in this.assemblies)
            {
                foreach (string resx in currentAssembly.GetManifestResourceNames())
                {
                    if (resx.EndsWith(".css"))
                    {
                        scanner = new Scanner(currentAssembly.GetManifestResourceStream(resx));
                        parser = new Parser(scanner);
                        parser.Parse();

                        if (parser.errors.count > 0)
                            return;
                        else
                        {
                            currentStyle = new DefaultStyle(parser.CSSDoc);
                            this.AddStyle(resx, currentStyle);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Add a CSS document to the cached list of ready to use styles.
        /// </summary>
        /// <param name="resourceName">The name of the CSS embedded file.</param>
        /// <param name="style">The implementation of the style.</param>
        private void AddStyle(string resourceName, IStyle style)
        {
            LoadedCustomizations.Add(new KeyValuePair<string,IStyle>(resourceName, style));
        }
    }
}
